package br.puc.rio.clarkWright;

import java.util.HashMap;
import java.util.Map;

import br.puc.rio.geoData.Pontos;
import br.puc.rio.geoData.geoUtilidades;

public class Roteiro {

	String nome;
	HashMap<Integer, Pontos> listaPontosRoteiro = new HashMap<>();
	Pontos pontoOrigem;
	double velocidadeKmPorHora;
	
	
	public double calctempoTotalDeParada (){
		double tempoTotal = 0;
		for (Map.Entry<Integer,Pontos> entry : listaPontosRoteiro.entrySet()){
			Pontos ponto = entry.getValue(); //aqui me retorna o objeto tipo ponto dentro do hashmap
			tempoTotal = tempoTotal + ponto.getTempoPonto();
		}
		return tempoTotal;
	}
	public double calctempoTotalEmMovimento (){
		System.out.println("Calc tempo em movi...");
		double tempoTotal = 0;
		double qtdArcos = listaPontosRoteiro.size()-1;
		for (int i =0; i<qtdArcos;i++){
			Pontos pOrigem = listaPontosRoteiro.get(i);
			Pontos pDestino = listaPontosRoteiro.get(i+1);
			double distanciaArco = geoUtilidades.distanciaEntrePontos(pOrigem, pDestino);
			double tempoArco = distanciaArco / velocidadeKmPorHora;
			tempoTotal = tempoTotal + tempoArco;
			}
		System.out.println("Calc tempo em movi finalizado!");
		return tempoTotal;
	}
	public double calcPesoTotal () {
		double pesoTotal = 0;
		for (Map.Entry<Integer,Pontos> entry : listaPontosRoteiro.entrySet()){
			Pontos ponto = entry.getValue(); //aqui me retorna o objeto tipo ponto dentro do hashmap
			pesoTotal = pesoTotal + ponto.getQuantidadePonto();
		}
		return pesoTotal;
	}
	public double calcValorTotal () {
		double valorTotal = 0;
		for (Map.Entry<Integer,Pontos> entry : listaPontosRoteiro.entrySet()){
			Pontos ponto = entry.getValue(); //aqui me retorna o objeto tipo ponto dentro do hashmap
			valorTotal = valorTotal + ponto.getValorCargaPonto();
		}
		return valorTotal;
	}
	public double calcTempoChegadaEretornoZona (){
		System.out.println("Calc entrada e saida da zona...");
		Pontos primeiroPontodaZona = listaPontosRoteiro.get(0);
		Pontos ultimoPontodaZona = listaPontosRoteiro.get(listaPontosRoteiro.size()-1);
	    double distanciaIda = geoUtilidades.distanciaEntrePontos(pontoOrigem, primeiroPontodaZona);
		double distanciaVolta = geoUtilidades.distanciaEntrePontos(ultimoPontodaZona, pontoOrigem);
		System.out.println("Calc entrada e saida da zona calculado!");
		return (distanciaIda + distanciaVolta) / velocidadeKmPorHora;
	}
	public double calcTempoTotalRoteiro (){
     return calctempoTotalDeParada () 
    		 + calctempoTotalEmMovimento() 
    		 + calcTempoChegadaEretornoZona();
	}
	public void addPontoRoteiro (Pontos ponto){
		if(listaPontosRoteiro.size()!=0){
			int posicaoDoNovoPontoNaLista = listaPontosRoteiro.size();
			listaPontosRoteiro.put(posicaoDoNovoPontoNaLista, ponto);
		} else {
			listaPontosRoteiro.put(0,ponto);
		}
	}
	
	public boolean verificarPontoNoRoteiro (Pontos ponto){
		boolean result=false;
		if(listaPontosRoteiro.containsValue(ponto)==true){
			result = true;
		}
		return result;
	}
	
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public Pontos getPontoOrigem() {
		return pontoOrigem;
	}
	public void setPontoOrigem(Pontos pontoOrigem) {
		this.pontoOrigem = pontoOrigem;
	}
	public HashMap<Integer, Pontos> getListaPontosRoteiro() {
		return listaPontosRoteiro;
	}
	public void setListaPontosRoteiro(HashMap<Integer, Pontos> listaPontosRoteiro) {
		this.listaPontosRoteiro = listaPontosRoteiro;
	}
	public double getVelocidadeKmPorHora() {
		return velocidadeKmPorHora;
	}
	public void setVelocidadeKmPorHora(double velocidadeKmPorHora) {
		this.velocidadeKmPorHora = velocidadeKmPorHora;
	}
	@Override
	public String toString() {
		return "Roteiro [Nome =" + nome
				+ ", Quantidade de Pontos =" + listaPontosRoteiro.size() 
				+ ", Pontos na lista = " + getNomePontosNaLista()
				+ ", Tempo total Roteiro =" + calcTempoTotalRoteiro()
				+ ", Carga total Roteiro = " + calcPesoTotal()
				+ ", Valor total Roteiro = " + calcValorTotal()
				+ ", Origem do Roteiro =" + pontoOrigem.getNomePonto()
				+ ", Velocidade no Roteiro =" + velocidadeKmPorHora + "]";
	}
	
	public String getNomePontosNaLista (){
		String listaNomesPontos = null;
		for (Map.Entry<Integer,Pontos> entry : listaPontosRoteiro.entrySet()){
			Pontos ponto = entry.getValue(); //aqui me retorna o objeto tipo ponto dentro do hashmap
			listaNomesPontos = listaNomesPontos + " + " + ponto.getNomePonto();
		}
		return listaNomesPontos;
	}
	public boolean isPointBeginOrEnd (Pontos ponto){
		boolean result=false;
		int qtdPontosNoRoteiro = listaPontosRoteiro.size()-1;
		Pontos pontoUltimoIndice = listaPontosRoteiro.get(qtdPontosNoRoteiro);
		Pontos pontoPrimeiroIndice = listaPontosRoteiro.get(0);
		
		if(pontoPrimeiroIndice==ponto){
			result = true;
		}
		if(pontoUltimoIndice==ponto){
			result = true;
		}
		return result;
	}
	
	
	public void addPontoRoteiroNaSequencia (Roteiro roteiro,Pontos pontoNoRoteiro, Pontos pontoAentrarNoRoteiro){
		   Pontos primeiroPontoRoteiro1 = roteiro.getListaPontosRoteiro().get(0);
		   Pontos ultimoPontoRoteiro1 = roteiro.getListaPontosRoteiro().get(roteiro.getListaPontosRoteiro().size()-1);
		 
		   int posicaoPontoLista = 0;
		   if(primeiroPontoRoteiro1 == pontoNoRoteiro){
			   listaPontosRoteiro.put(posicaoPontoLista, pontoAentrarNoRoteiro);
			   posicaoPontoLista++;
			   for (Map.Entry<Integer,Pontos> entry : roteiro.getListaPontosRoteiro().entrySet()){
					Pontos ponto = entry.getValue(); 
					listaPontosRoteiro.put(posicaoPontoLista, ponto);
					posicaoPontoLista++;		
			   }		
		   } else {
		   if(ultimoPontoRoteiro1 == pontoNoRoteiro) {
			   for (Map.Entry<Integer,Pontos> entry : roteiro.getListaPontosRoteiro().entrySet()){
					Pontos ponto = entry.getValue(); 
					listaPontosRoteiro.put(posicaoPontoLista, ponto);
					posicaoPontoLista++;		
			   }
			   listaPontosRoteiro.put(posicaoPontoLista,pontoAentrarNoRoteiro);
		     }	
		   }
	}
	
	
	
}
